package com.bitejiuyeke.job_publish.controller;

import com.bitejiuyeke.job_publish.common.AppResult;
import com.bitejiuyeke.job_publish.common.PageResult;
import com.bitejiuyeke.job_publish.common.ResultCode;
import com.bitejiuyeke.job_publish.config.AppConfig;
import com.bitejiuyeke.job_publish.controller.params.*;
import com.bitejiuyeke.job_publish.enums.PrivacyStateEnum;
import com.bitejiuyeke.job_publish.enums.StateEnum;
import com.bitejiuyeke.job_publish.enums.VerifyCodeTypeEnum;
import com.bitejiuyeke.job_publish.exception.ApplicationException;
import com.bitejiuyeke.job_publish.model.*;
import com.bitejiuyeke.job_publish.service.*;
import com.bitejiuyeke.job_publish.utils.JWTUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.PositiveOrZero;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author 比特就业课
 */
// API描述
@Tag(name = "用户操作相关接口")
// 日志
@Slf4j
// 参数校验
@Validated
// Controller注解，返回的对象用JSON形式表示
@RestController
// 路径映射
@RequestMapping("/user")
public class UserController {

    @Resource
    private IUserService userService;
    @Resource
    private IVerificationCodeService vcService;
    @Resource
    private IFavoriteRecordService favoriteRecordService;
    @Resource
    private ISendRecordService sendRecordService;
    @Resource
    private IOfferService offerService;


    @Operation(summary = "用户注册")
    @PostMapping("/register")
    public AppResult register (@Validated @RequestBody UserRegisterDTO param) {
        // 校验两次密码是否一致
        if (!param.getPassword().equals(param.getRepeatPassword())) {
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME));
        }
        // 回销验证码
        VerificationCode vc = new VerificationCode();
        vc.setPhoneNum(param.getPhoneNum());
        vc.setCode(param.getCode());
        vc.setType((byte) VerifyCodeTypeEnum.REGISTER.getCode());
        vcService.verify(vc);

        // 注册新用户
        User user = new User();
        user.setName(param.getName());
        user.setPhoneNum(param.getPhoneNum());
        user.setPassword(param.getPassword());
        userService.create(user);
        // 响应
        return AppResult.success();
    }


    @Operation(summary = "用户登录")
    @PostMapping("/login")
    public AppResult<String> login (@Validated @RequestBody UserLoginDTO param) {
        // 登录校验
        User user = userService.loginByPhoneNum(param.getPhoneNum(), param.getPassword());
        // 生成令牌
        Map<String, Object> claim = new HashMap<>();
        claim.put(AppConfig.TOKEN_USER_ID, user.getId().toString());
        claim.put(AppConfig.TOKEN_USER_NAME, user.getName());
        String token = JWTUtils.genJwt(claim);
        // 返回响应
        return AppResult.success(token);
    }

    @Operation(summary = "用户详情")
    @Parameter(name = "id", description = "用户Id", in = ParameterIn.QUERY)
    @GetMapping("/details")
    public AppResult details (HttpServletRequest request,
                              @RequestParam(value = "id", required = false) Long id) {
        // 如果传入的Id为空，则获取当前登录用户详情
        if (id == null) {
            id = (Long) request.getAttribute(AppConfig.TOKEN_USER_ID);
        }
        // 查询用户信息
        User user = userService.selectById(id);
        return AppResult.success(user);
    }

    @Operation(summary = "修改密码")
    @PostMapping("/modifyPwd")
    public AppResult modifyPwd (HttpServletRequest request,
                                @Validated @RequestBody UserModifyPwdDTO param) {
        // 校验密码与重复密码是否相同
        if (!param.getNewPassword().equals(param.getRepeatPassword())) {
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME));
        }
        // 获取用户Id
        Long userId = (Long) request.getAttribute(AppConfig.TOKEN_USER_ID);
        // 修改密码
        userService.modifyPassword(userId, param.getNewPassword(), param.getOldPassword());
        // 响应结果
        return AppResult.success();
    }

    @Operation(summary = "修改用户基本信息")
    @PostMapping("/modify")
    public AppResult<User> modify (HttpServletRequest request,
                             @Validated @RequestBody UserModifyInfoDTO param) {
        // 获取用户Id
        Long userId = (Long) request.getAttribute(AppConfig.TOKEN_USER_ID);
        // 封装修改的用户对象
        User user = new User();
        // 复制对象属性
        BeanUtils.copyProperties(param, user);
        // 用户Id，用从TOKEN中解析到的用户Id
        user.setId(userId);

//        user.setMajorId(param.getMajorId());
//        user.setName(param.getName());
//        user.setSNo(param.getSNo());
//        user.setGender(param.getGender());
//        user.setEnrollment(param.getEnrollment());
//        user.setIsTeacher(param.getIsTeacher());
//        user.setTag(param.getTag());
//        user.setPrivacyState(param.getPrivacyState());
//        user.setRemark(param.getRemark());

        // 调用Service
        userService.modifyInfo(user);
        // 获取用户信息
        User newUser = userService.selectById(user.getId());

        // 返回响应
        return AppResult.success(newUser);
    }

    @Operation(summary = "修改私隐状态")
    @PutMapping("/modifyPrivateState")
    public AppResult<User> modifyPrivateState (HttpServletRequest request,
                                         @Validated @PositiveOrZero(message = "请隐私状态") @RequestParam("privacyState") Byte privacyState) {
        // 获取用户Id
        Long userId = (Long) request.getAttribute(AppConfig.TOKEN_USER_ID);
        // 调用Service
        userService.modifyPrivateState(userId, privacyState);
        // 获取用户
        User user = userService.selectById(userId);
        return AppResult.success(user);
    }

    @Operation(summary = "修改电话号码")
    @PostMapping("/modifyPhoneNum")
    public AppResult modifyPhoneNum () {

        return AppResult.success();
    }

    @Operation(summary = "修改邮箱地址")
    @PostMapping("/modifyEmail")
    public AppResult modifyEmail () {

        return AppResult.success();
    }

    @Operation(summary = "上传图片")
    @PostMapping("/uploadAvatar")
    public AppResult<User> uploadAvatar (HttpServletRequest request,
                                @RequestPart("avatar") MultipartFile avatar) {
        // 这里可以校验后缀名是不是图片
        if (avatar == null) {
            return AppResult.failed(ResultCode.FAILED_UPLOAD_IS_NULL);
        }
        // 获取用户Id
        Long userId = (Long) request.getAttribute(AppConfig.TOKEN_USER_ID);
        // 调用Service
        User user = userService.uploadAvatar(userId, avatar);
        // 响应
        return AppResult.success(user);
    }

    @Operation(summary = "删除头像")
    @DeleteMapping("/deleteAvatar")
    public AppResult<User> deleteAvatar (HttpServletRequest request) {
        // 获取用户Id
        Long userId = (Long) request.getAttribute(AppConfig.TOKEN_USER_ID);
        User user = userService.deleteAvatar(userId);
        return AppResult.success(user);
    }

    @Operation(summary = "上传简历")
    @PostMapping("/uploadResume")
    public AppResult<User> uploadResume (HttpServletRequest request,
                                 @RequestPart("file") MultipartFile resume) {
        // 校验
        if (resume == null) {
            return AppResult.failed(ResultCode.FAILED_UPLOAD_IS_NULL);
        }
        // 获取用户Id
        Long userId = (Long) request.getAttribute(AppConfig.TOKEN_USER_ID);
        // 调用Service
        User user = userService.uploadResume(userId, resume);
        // 响应
        return AppResult.success(user);
    }

    @Operation(summary = "删除简历")
    @DeleteMapping("/deleteResume")
    public AppResult<User> deleteResume (HttpServletRequest request) {
        // 获取用户Id
        Long userId = (Long) request.getAttribute(AppConfig.TOKEN_USER_ID);
        User user = userService.deleteResume(userId);
        return AppResult.success(user);
    }

    @Operation(summary = "首页显示的用户列表")
    @GetMapping("/indexPages")
    public AppResult<PageResult<User>> indexPages (@Validated IndexUserPageDTO param) {
        // 构造条件对象
        User user = new User();
        BeanUtils.copyProperties(param, user);
        // 设置查询条件
        user.setState((byte) StateEnum.NORMAL.getCode());
        user.setPrivacyState((byte) PrivacyStateEnum.PUBLIC.getCode());
        // 查询
        PageResult<User> pageResult = userService.selectByPage(user);
        return AppResult.success(pageResult);
    }

    @Operation(summary = "用户收藏列表")
    @GetMapping("/favorites")
    public AppResult<PageResult<FavoriteRecord>> favorite (HttpServletRequest request,
                                                           @Validated UserFavoritePageDTO param) {
        // 获取用户Id
        Long userId = (Long) request.getAttribute(AppConfig.TOKEN_USER_ID);
        param.setUserId(userId);
        // 查询条件对象
        FavoriteRecord favoriteRecord = new FavoriteRecord();
        BeanUtils.copyProperties(param, favoriteRecord);
        PageResult<FavoriteRecord> list = favoriteRecordService.selectPageByUser(favoriteRecord);
        return AppResult.success(list);
    }

    @Operation(summary = "用户投递列表")
    @GetMapping("/sendRecords")
    public AppResult<PageResult<SendRecord>> sendRecord (HttpServletRequest request,
                                                       @Validated UserSendRecordPageDTO param) {
        // 获取用户Id
        Long userId = (Long) request.getAttribute(AppConfig.TOKEN_USER_ID);
        param.setUserId(userId);
        // 查询条件对象
        SendRecord record = new SendRecord();
        BeanUtils.copyProperties(param, record);
        PageResult<SendRecord> list = sendRecordService.selectPageByUser(record);
        return AppResult.success(list);
    }

    @Operation(summary = "用户Offer列表")
    @GetMapping("/offers")
    public AppResult<PageResult<Offer>> offers (HttpServletRequest request,
                                                    @Validated UserOfferPageDTO param) {
        // 获取用户Id
        Long userId = (Long) request.getAttribute(AppConfig.TOKEN_USER_ID);
        param.setUserId(userId);
        // 查询条件对象
        Offer record = new Offer();
        BeanUtils.copyProperties(param, record);
        PageResult<Offer> list = offerService.selectPageByUser(record);
        return AppResult.success(list);
    }
}
